import axios, { AxiosError, AxiosInstance } from 'axios';
import {
  InternalAxiosRequestConfig,
  AxiosResponse,
  AxiosRequestConfig,
} from 'axios';
import { message } from 'antd';

interface QueueItem {
  options: AxiosRequestConfig;
  resolve: (value: unknown) => void;
  reject: (error: unknown) => void;
}

const axiosInstance: AxiosInstance = axios.create({
  timeout: 120 * 1000,
  baseURL: import.meta.env.VITE_BASE_AXIOS_URL || '',
});

class RequestQueue {
  private queue: QueueItem[] = [];
  private activeCount = 0;
  private readonly maxConcurrent = 3;

  async add(options: AxiosRequestConfig): Promise<unknown> {
    return new Promise((resolve, reject) => {
      const queueItem = { options, resolve, reject };
      if (options.headers && options.headers.pop) {
        delete options.headers.pop;
        if (this.activeCount < this.maxConcurrent) {
          this.processRequest(queueItem);
        } else {
          this.queue.push(queueItem);
        }
      } else {
        this.processNormalRequest(queueItem);
      }
    });
  }

  private async processRequest(queueItem: QueueItem) {
    this.activeCount++;
    try {
      const response = await axiosInstance(queueItem.options);
      queueItem.resolve(response.data);
    } catch (error) {
      queueItem.reject(error);
    } finally {
      this.activeCount--;
      this.processNextRequest();
    }
  }

  private async processNormalRequest(queueItem: QueueItem) {
    try {
      const response = await axiosInstance(queueItem.options);
      queueItem.resolve(response.data);
    } catch (error) {
      queueItem.reject(error);
    }
  }

  private processNextRequest() {
    if (this.queue.length > 0 && this.activeCount < this.maxConcurrent) {
      const nextRequest = this.queue.shift();
      if (nextRequest) {
        this.processRequest(nextRequest);
      }
    }
  }

  clearQueue() {
    this.queue = [];
    this.activeCount = 0;
  }
}

const requestQueue = new RequestQueue();

// 存储需要发送的请求，以及对应的中止控制器
const abortControllerMap: Map<string, AbortController> = new Map();

axiosInstance.interceptors.request.use((req: InternalAxiosRequestConfig) => {
  const controller = new AbortController();
  req.signal = controller.signal;
  abortControllerMap.set(req.url || '', controller);

  // 自动携带token
  const token = localStorage.getItem('token');
  if (token) {
    req.headers['Authorization'] = `Bearer ${token}`;
  }

  return req;
});

axiosInstance.interceptors.response.use(
  (res: AxiosResponse) => {
    const url = res.config.url || '';
    const code = res.data?.code;

    // 处理业务状态码
    switch (code) {
      case 200:
        break;
      case 401:
        message.error('登录过期，请重新登录');
        setTimeout(() => {
          localStorage.removeItem('token');
          window.location.href = '/login';
        }, 1500);
        break;
      // case 500:
      //   message.error('服务器错误');
      //   break;
      default:
        if (res.data?.message) {
          message.error(res.data.message);
        }
        break;
    }

    abortControllerMap.delete(url);
    return res;
  },
  (error: AxiosError) => {
    if (error.response?.status === 401) {
      message.error('登录过期，请重新登录');
      setTimeout(() => {
        localStorage.removeItem('token');
        window.location.href = '/login';
      }, 1500);
    } else {
      message.error(error.message || '请求失败');
    }
    return Promise.reject(error);
  }
);

// 对外暴露请求方法
const service = {
  request: (config: AxiosRequestConfig) => {
    return requestQueue.add(config);
  },
  cancelRequest: (url: string | string[]) => {
    const urlList = Array.isArray(url) ? url : [url];
    for (const _url of urlList) {
      abortControllerMap.get(_url)?.abort();
      abortControllerMap.delete(_url);
    }
  },
  cancelAllRequest() {
    for (const controller of abortControllerMap.values()) {
      controller.abort();
    }
    abortControllerMap.clear();
    requestQueue.clearQueue();
  },
};

export { service };
export default axiosInstance;
